package com.blz.flare.parser.impl;

import com.blz.flare.crawler.PostException;
import com.blz.flare.parser.ContentParser;
import com.blz.flare.parser.ParseResult;
import com.blz.flare.parser.ParseResultImpl;
import org.apache.lucene.util.ArrayUtil;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.sax.BodyContentHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URI;
import java.util.*;

/**
 * {@see Tika} implementation of the {@link com.blz.flare.parser.ContentParser}.
 */
public class TIKAContentParser
        implements ContentParser {

    private static final Logger logger = LoggerFactory.getLogger(TIKAContentParser.class);
    
    private List<String> supportedContentTypes = new ArrayList<String>();

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean supports(String contentType) {
        return supportedContentTypes.contains(contentType);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ParseResult parse(URI uri)
            throws Exception {

        // create the parse result
        ParseResultImpl result = new ParseResultImpl();

        // grab the file
        File file = new File(uri);

        // if it's directory, get all the out uris.
        if (file.isDirectory()) {
            List<URI> uriList = new ArrayList<URI>();

            for (String f : file.list()) {
                uriList.add(new URI(f));
            }

            // set the results and return
            result.setParsedUris(uriList);
            return result;
        }

        // create the tika classes needed to parse
        Parser parser = new AutoDetectParser();
        final Metadata metadata = new Metadata();
        final BodyContentHandler handler = new BodyContentHandler();
        InputStream input = null;

        // parse the file
        try {

            input = new FileInputStream(file);
            parser.parse(input, handler, metadata, new ParseContext());

            logger.debug("Title: " + metadata.get("title"));
            logger.debug("Author: " + metadata.get("Author"));

        } catch (Exception ex) {
            logger.error("error parsing file: "+uri, ex);
        } finally {
            input.close();
        }

        for (String name : metadata.names()) {
            result.getData().put(name, metadata.get(name));
        }
        result.setText(handler.toString());
        result.setText(uri.toString());
        
        return result;
    }

    /**
     * @param supportedContentTypes an <i>injected</i> list of content types that are supported by this parser.
     */
    public void setSupportedContentTypes(List<String> supportedContentTypes) {
        this.supportedContentTypes = supportedContentTypes;
    }
}
